package main

import (
	"context"
	"fmt"
	"gfast/app/system/dao"
	"gfast/app/system/model"
	"gfast/app/system/service"
	"github.com/tidwall/gjson"
	"os"
	"strings"
)

func main() {
	params := os.Args[1:]
	if len(params) == 0 {
		params = []string{""}
	}

	switch params[0] {
	case "gen":
		gen(params[1:])
	case "like":
		params = params[1:]
		if len(params) == 0 {
			return
		}

		keyword := params[0]
		models := listAll()
		for k, v := range models {
			title := v.Get("title").String()
			if strings.Contains(k, keyword) || strings.Contains(title, keyword) {
				fmt.Println(k, title)
			}
		}
	case "group":
		params = params[1:]
		if len(params) == 0 {
			params = []string{""}
		}

		switch params[0] {
		case "gen":
			params = params[1:]

			groups := map[string]struct{}{}
			for _, name := range params {
				groups[name] = struct{}{}
			}
			models := listAll()
			list := make([]string, 0)
			for k, v := range models {
				group := v.Get("group").String()
				if _, has := groups[group]; has {
					list = append(list, k)
				}
			}
			gen(list)
		case "equal":
			params = params[1:]
			if len(params) == 0 {
				return
			}
			name := params[0]

			models := listAll()
			for k, v := range models {
				group := v.Get("group").String()
				if name == group {
					fmt.Println(k, v.Get("title").String())
				}
			}
		default:
			groups := map[string]struct{}{}
			models := listAll()
			for _, v := range models {
				group := v.Get("group").String()
				groups[group] = struct{}{}
			}
			for k := range groups {
				fmt.Println(k)
			}
		}
	default:
		models := listAll()
		for k, v := range models {
			fmt.Println(k, v.Get("title").String())
		}
	}
}

func listAll() map[string]gjson.Result {
	es, err := os.ReadDir("data/schema/")
	if err != nil {
		panic(err)
	}
	models := map[string]gjson.Result{}
	for _, e := range es {
		if !e.IsDir() && strings.HasSuffix(e.Name(), ".model.json") {
			data, err := os.ReadFile("data/schema/" + e.Name())
			if err != nil {
				panic(err)
			}
			gjson.ParseBytes(data).ForEach(func(key, json gjson.Result) bool {
				switch _key := key.String(); _key {
				case "$id", "$schema", "$ref", "$comment":
					// 忽略schema文件需要的属性
				default:
					// 忽略以`__`开头的，被注释掉的模型
					if !strings.HasPrefix(_key, "__") {
						models[_key] = json
					}
				}
				return true
			})
		}
	}
	return models
}

func gen(list []string) {
	models := listAll()
	tables := make([]*Table, 0)
	parser := Parser{
		models: models,
		handleAssocModel: func(table *Table) {
			tables = append(tables, table)
		},
		handleOptions: func(key string, title string, options gjson.Result) {
			if !service.SysDictType.ExistsDictType(key) {
				_ = service.SysDictType.Add(&model.SysDictTypeAddReq{
					DictName: title,
					DictType: key,
					Status:   1,
					Remark:   "",
					CreateBy: 0,
				})
				list := make([]interface{}, 0)
				for index, option := range options.Array() {
					value := option.Get("value").String()
					label := option.Get("label").String()
					list = append(list, &model.SysDictData{
						DictLabel: label,
						DictValue: value,
						DictType:  key,
						DictSort:  index,
						CssClass:  "",
						ListClass: "",
						IsDefault: 0,
						Status:    0,
						Remark:    "",
						CreateBy:  0,
					})
				}
				_, _ = dao.SysDictData.Insert(list)
			}
		},
	}
	for _, name := range list {
		if json, has := models[name]; has {
			table := parser.parseModel(name, json, InlineFlag)
			tables = append(tables, table)
		}
	}

	err := Gen.Write(tables, context.Background())
	if err != nil {
		fmt.Println("生成失败", err)
		return
	}
	fmt.Println("生成成功")
}
